﻿/*!	@file	r_debug_profile_server.h
	@brief	リアルタイムプロファイラ
Copyright (c) 2010 Yuya Yamaguchi

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef _R_DEBUG_PROFILE_SERVER_H_
#define _R_DEBUG_PROFILE_SERVER_H_

#include "../r_type.h"
#include "../util/r_util_doublebuffer.h"

namespace r{
	namespace thread{
		class Server;
		namespace profile{
			class Client;
		}
	}
}

namespace r{
	namespace thread{
		namespace profile{
			enum eRDebugProfileServer {
				eRDebugProfileServer_MaxProfileNum = 128,			//!< 最大プロファイルノード数
			};

			//! プロファイル情報を記述するノード
			class ServerNode
			{
			public:
				ServerNode()
					:
					parent ( NULL ),
					child ( NULL ),
					sibling ( NULL ),
					type ( 0 ),
					depth ( 0 ),
					intime ( 0 ),
					outtime ( 0 ) {
				}
				void			clear();
			public:
				const r_char	*name;			//!< 名前
				r_ui32			count;			//!< コール回数
				r_time			time;			//!< 累計実行時間
				r_time			intime;			//!< 初回呼び出し時間
				r_time			outtime;		//!< 最終実行完了時間
				r_time			mintime;		//!< 最短処理時間
				r_time			maxtime;		//!< 最長処理時間
				r_ui8			depth;			//!< 深さ
				r_si8			type;			//!< 種別
				ServerNode		*parent;		//!< 親ノード
				ServerNode		*child;			//!< 子ノード
				ServerNode		*sibling;		//!< 兄弟ノード
			};

			//! プロファイルサーバ
			/*! このサーバを各スレッドで持つことでスレッド単位でのプロファイルが可能になります
			*/
			class Server
			{
				friend class r::thread::Server;
			protected:
				//! コンストラクタ
				Server ( void );
				//! デストラクタ
				virtual ~Server ( void );
			public:
				// システム呼び出し
				//! フレームのプロファイルを開始する
				void			begine ( void );
				//! システムのプロファイルを終了する
				void			end ( void );
			public:
				//! プロファイル突入
				void			inProfile ( Client &profile );
				//! プロファイル抜け
				void			outProfile ( Client &profile );
				//! 基準tickの取得
				r_time			getInTick() const;
			public:
				//! プロファイル走査
				/*!
				*/
				const	ServerNode*	getTopNode() const;
			protected:
			private:
				//! 入力基準tick
				r_time							inTick;
				//! 現在のノードの取り出し位置
				r_ui32							curNodeIndex;
				//! 現在のプロファイルノード
				ServerNode*		current;
				//! プロファイルデータ
				r_tm_doubleBuffer<ServerNode[eRDebugProfileServer_MaxProfileNum]>		profileNode;
			};
		}
	}
}

#endif // _R_DEBUG_PROFILE_SERVER_H_
